#pragma once
#include "Socket2.hpp"
#include"EventLoop.hpp"
#include <memory>class Connection;
typedef std::shared_ptr<Connection> ConnectionPtr;
/// @brief 把一个连接结构话理应由socket和channel
class Connection : public std::enable_shared_from_this<Connection> ////却保从原始指针到倒多个共享的安全
{
    using CloseCallback = std::function<void(const ConnectionPtr &)>;

private:
    Socket _socket;
    int _fd;
    Channel _channel;
    CloseCallback _close_cb; // 给上级调用者用当这一层要被释放时逐级往上释放资源
    EventLoop &_event_loop;

private:
    void Close()
    {
        _channel.Remove();
        if (_close_cb)
            _close_cb(shared_from_this());
        LOG(LogLevel::DEBUG) << "???";
    }

    void CloseInLoop()
    {
        _event_loop.QueueInLOOP([this]
                                { this->Close(); }); // 延迟销毁
    }

    void HandleClose() { CloseInLoop(); }

    void HandleRead()
    {
        auto self = shared_from_this(); // 使得上层销毁不影响本体
        char buf[2048];
        int ret = _socket.NoneBlockRecv(buf, sizeof(buf));
        if (ret < 0)
        {
            LOG(LogLevel::WARNING) << "fd:" << _socket.Fd();
            CloseInLoop();
            return;
        }
        std::cout << buf << std::endl; // 这里应该是回调
    }

public:
    Connection(int fd, /*Poller &poller*/ EventLoop &event_loop) : _socket(fd),
                                                                   _channel(fd, event_loop),
                                                                   _fd(fd),
                                                                   _event_loop(event_loop)
    {
        _channel.SetReadCallback(std::bind(&Connection::HandleRead, this));
        _channel.SetCloseCallback(std::bind(&Connection::HandleClose, this));
        _channel.SetErrorCallback(std::bind(&Connection::HandleClose, this));
        _channel.EnableRead();
    }

    void SetCloseCallback(const CloseCallback &cb) { _close_cb = cb; }
    int Fd() const { return _fd; }
};
class Acceptor
{
private:
    Socket _socket;
    Channel _channel;
    // Poller &_poller;
    //  std::vector<ConnectionPtr> _connections;
    EventLoop &_event_loop;
    std::unordered_map<int, ConnectionPtr> _connections;

public:
    Acceptor(uint16_t port, EventLoop &event_loop) : _channel(CreateServer(port), event_loop), _event_loop(event_loop)
    {
        _channel.SetReadCallback([this]()
                                 { this->HandleRead(); });
        _channel.EnableRead();
    }

private:
    int CreateServer(uint16_t port)
    {
        if (_socket.CreatTcpServer(port))
            return _socket.Fd();
        else
            LOG(LogLevel::ERROR) << "create acceptor failure";
        abort();
    }
    /// @brief 在connections管理中删掉失效连接
    /// @param conn

    void ClientClose(const ConnectionPtr conn)
    {
        //_connections.erase(conn)
        LOG(LogLevel::DEBUG) << "HandleClientCloseCallback";
        auto ret = _connections.find(conn->Fd());
        if (ret != _connections.end())
        {
            _connections.erase(ret);
            LOG(LogLevel::DEBUG) << "remove conn from _connections success";
        }
    }
    void HandleClientCloseCallback(const ConnectionPtr conn)
    {
        _event_loop.QueueInLOOP([this, conn]()
                                { this->ClientClose(conn); });
    }
    void HandleRead()
    {
        int fd = _socket.Accept();
        if (fd < 0)
        {
            LOG(LogLevel::ERROR) << "Accept failure";
            return;
        }
        LOG(LogLevel::INFO) << "accept a new link " << fd;
        Connection *cli = new Connection(fd, _event_loop);
        cli->SetCloseCallback([this](const auto &arg)
                              { this->HandleClientCloseCallback(arg); });
        _connections.insert(std::make_pair(fd, std::shared_ptr<Connection>(cli)));
    }
};

